fix(driver-sql): round-trip rating/slider/toggle with type fidelity#2025
Merged
Conversation
rating/slider/toggle (and progress) fell to the DDL switch `default`
case → table.string, giving the column TEXT affinity. SQLite then
coerced the written number/boolean to a string ('4' not 4, '1' not
true): the value persisted but the JS type leaked on read. On a
low-code platform where an AI authors arbitrary field types, a field
that silently returns the wrong type is a runtime-fidelity trap the
static gates and value-loss tests don't catch.
- map rating/slider/progress → REAL (numeric) column
- map toggle → boolean column + register it in booleanFields so the
read path coerces stored 1/0 back to a real JS boolean
- fold object-valued record/video/audio into the shared
JSON_COLUMN_TYPES source, and drive the DDL default off that set so
the column-type switch and isJsonField can no longer drift
- driver-layer unit test (sql-driver-numeric-fidelity) + lift the
xfail quarantine on rating/slider/toggle in the dogfood matrix
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 2 package(s): 8 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
os-zhuang
added a commit
that referenced
this pull request
Jun 18, 2026
…ns + extend dogfood matrix (#2028) The #2025 column-affinity fix only governs newly created columns: SQLite never alters a column's type in place and the reconciler only adds missing columns, so a rating/slider/progress column created before the fix keeps TEXT affinity and still reads back '4' not 4. - add a read-side numeric coercion (numericFields registry, single- sourced from NUMERIC_SCALAR_TYPES) that coerces numeric-looking stored strings back to numbers on read — mirroring the dateFields legacy repair — so fidelity no longer depends on column affinity alone; null and non-numeric junk are preserved (not 0/NaN) - unit test: reproduce a legacy TEXT column and prove it self-heals - extend the dogfood HTTP matrix to guard progress/record/video/audio over real HTTP (previously only driver-unit-tested) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This was referenced Jun 18, 2026
This was referenced Jun 18, 2026
os-zhuang
added a commit
that referenced
this pull request
Jun 27, 2026
feat(studio): remove the "Local / Custom" stopgap scope from the package selector (ADR-0070 D5) (#2025) objectui@17ae00cb569379298a99d21e4c52432c9def43aa
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The dogfood field-zoo round-trip test (
#2022) surfaced three authorable field types that persist but read back with the wrong JS type over the REST data API:rating4'4'(string)slider25'25'(string)toggletrue'1'(string)The value is not lost — only the type leaks. On a low-code platform where an AI authors arbitrary field types, a field that silently returns the wrong type is a runtime-fidelity trap the static gates and value-loss tests don't catch.
Root cause (
packages/plugins/driver-sql/src/sql-driver.ts)Two coupled gaps:
createColumn's DDL switch had no case forrating/slider/toggle/progress, so they fell todefault → table.string= TEXT affinity. SQLite then coerced the written number/boolean to a string on storage.number/currency/percentworked only because of explicittable.floatcases;booleanbecause of atable.booleancase + read coercion.formatOutputre-types boolean columns via thebooleanFieldsregistry, keyed ontype === 'boolean'only —togglewas never registered.Fix
rating/slider/progress→ REAL (numeric) column.toggle→ boolean column and registered inbooleanFieldsso stored1/0coerce back to a real JS boolean.vector/composite/repeaterwere already JSON-safe;record/video/audiowere the same latent leak (object → TEXT), now folded into the sharedJSON_COLUMN_TYPESset.treestores a reference id (string→string, no leak — unchanged).defaultcase now derives JSON-vs-string fromJSON_COLUMN_TYPES, so the column-type switch andisJsonField(read side) can no longer drift.Verification
sql-driver-numeric-fidelity.test.tsassertstypeoffidelity for rating/slider/progress/toggle + record/video/audio. Red-proof done: all 3 fail without the fix, pass with it.xfailquarantine on rating/slider/toggle in the dogfood matrix → real-HTTP round-trip test now 22 passed (the formerly-quarantined three turn green — exactly the signal theit.failsquarantine was designed to force).🤖 Generated with Claude Code